#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include "curlrequest.h"


struct MemoryStruct
{
    char *memory;
    size_t size;
};


static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
    size_t realsize = size * nmemb;
    struct MemoryStruct *mem = (struct MemoryStruct *)userp;

    char *ptr = realloc(mem->memory, mem->size + realsize + 1);
    if (!ptr)
    {
        printf("内存申请失败！\n");
        return 0;
    }

    mem->memory = ptr;
    memcpy(&(mem->memory[mem->size]), contents, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = 0;

    return realsize; // 【注意】
}


static int OnDebug(CURL *, curl_infotype itype, char * pData, size_t size, void *)
{
    if (itype == CURLINFO_TEXT)
    {
        //printf("[TEXT]%s\n", pData);
    }
    else if (itype == CURLINFO_HEADER_IN)
    {
        printf("[HEADER_IN]%s\n", pData);
    }
    else if (itype == CURLINFO_HEADER_OUT)
    {
        printf("[HEADER_OUT]%s\n", pData);
    }
    else if (itype == CURLINFO_DATA_IN)
    {
        printf("[DATA_IN]%s\n", pData);
    }
    else if (itype == CURLINFO_DATA_OUT)
    {
        printf("[DATA_OUT]%s\n", pData);
    }
    return 0;
}


char* Request(CurlMethod cm, char* url, void* data, char** headers_append, int header_cout)
{
    struct MemoryStruct chunk;
    struct curl_slist* headers = NULL;
    chunk.memory = malloc(1);
    chunk.size = 0;

    curl_global_init(CURL_GLOBAL_ALL);

    CURL* curl_handle = curl_easy_init();
    /* curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1); */
    /* curl_easy_setopt(curl_handle, CURLOPT_DEBUGFUNCTION, OnDebug); */
    curl_easy_setopt(curl_handle, CURLOPT_URL, url);
    headers = curl_slist_append(headers, "Content-Type: application/json;charset=UTF-8");
    curl_slist_append(headers, "Accept: application/json");
    if (headers_append != NULL) {
        for (int i = 0; i < header_cout; i++) {
            curl_slist_append(headers, headers_append[i]);
        }
    }
    curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
    if (cm == POST)
    {
        /* printf("method is post\n"); */
        /* curl_easy_setopt(curl_handle, CURLOPT_POST, 1); */
        curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, data);  // post参数
        /* curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, strlen(data));  // post参数 */
    }
    curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
    /* curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, "Content-Type: application/json"); */
    /* curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); */


    CURLcode res = curl_easy_perform(curl_handle);
    if (res != CURLE_OK)
    {
        fprintf(stderr, "curl_easy_perform() 执行失败，原因是 %s\n", curl_easy_strerror(res));
    }
    else
    {
        /* printf("接收到网页数据%lu字节\n", (unsigned long)chunk.size); */
        /* printf("%s\n", chunk.memory); */

        // 可以在这里进行内存中的HTML解析操作
        // ......
    }
    curl_easy_cleanup(curl_handle);
    curl_slist_free_all(headers);
    char * buf = malloc(chunk.size * sizeof(char) + 1);
    strcpy(buf, chunk.memory);
    free(chunk.memory);
    curl_global_cleanup();
    return buf;
}

